/* * org.openmicroscopy.shoola.util.ui.treetable.TreeTable * *------------------------------------------------------------------------------ * Copyright (C) 2006-2007 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.ui.treetable; //Java imports import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.DefaultCellEditor; import javax.swing.Icon; import javax.swing.JCheckBox; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.table.TableCellRenderer; import javax.swing.tree.TreePath; //Third-party libraries import org.jdesktop.swingx.JXTreeTable; import org.jdesktop.swingx.decorator.Highlighter; import org.jdesktop.swingx.decorator.HighlighterFactory; import org.jdesktop.swingx.table.ColumnHeaderRenderer; import org.jdesktop.swingx.treetable.MutableTreeTableNode; import org.jdesktop.swingx.treetable.TreeTableModel; //Application-internal dependencies import org.openmicroscopy.shoola.util.ui.UIUtilities; import org.openmicroscopy.shoola.util.ui.treetable.editors.BooleanCellEditor; import org.openmicroscopy.shoola.util.ui.treetable.editors.NumberCellEditor; import org.openmicroscopy.shoola.util.ui.treetable.editors.StringCellEditor; import org.openmicroscopy.shoola.util.ui.treetable.model.OMETreeNode; import org.openmicroscopy.shoola.util.ui.treetable.renderers.BooleanCellRenderer; import org.openmicroscopy.shoola.util.ui.treetable.renderers.IconCellRenderer; import org.openmicroscopy.shoola.util.ui.treetable.renderers.NumberCellRenderer; import org.openmicroscopy.shoola.util.ui.treetable.renderers.SelectionHighLighter; /** * A customized {@link JXTreeTable}. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $Date: $) * </small> * @since OME3.0 */ public class OMETreeTable extends JXTreeTable { /** A map of the default cell editors in the table. */ protected static final Map<Class<?>, DefaultCellEditor> DEFAULT_EDITORS; /** A map of the default cell renderers in the table. */ protected static final Map<Class<?>, TableCellRenderer> DEFAULT_RENDERERS; static { DEFAULT_RENDERERS = new HashMap<Class<?>, TableCellRenderer>(); DEFAULT_RENDERERS.put(Boolean.class, new BooleanCellRenderer()); DEFAULT_RENDERERS.put(Long.class, new NumberCellRenderer()); DEFAULT_RENDERERS.put(Integer.class, new NumberCellRenderer()); DEFAULT_RENDERERS.put(Float.class, new NumberCellRenderer()); DEFAULT_RENDERERS.put(Double.class, new NumberCellRenderer()); DEFAULT_RENDERERS.put(String.class, new NumberCellRenderer(SwingConstants.LEFT)); DEFAULT_RENDERERS.put(Icon.class, new IconCellRenderer()); // defaultTableRenderers.put(Color.class, new ColourCellRenderer()); DEFAULT_EDITORS = new HashMap<Class<?>, DefaultCellEditor>(); DEFAULT_EDITORS.put(Boolean.class, // new BooleanCellEditor(new JCheckBox())); new BooleanCellEditor((JCheckBox) DEFAULT_RENDERERS.get(Boolean.class))); DEFAULT_EDITORS.put(Integer.class, new NumberCellEditor(new JTextField())); DEFAULT_EDITORS.put(String.class, new StringCellEditor(new JTextField())); } /** Tree expansion listener. */ protected TreeExpansionListener treeExpansionListener; /** The mouse listener. */ //protected MouseListener mouseListener; /** Initializes the table. */ private void initialize() { ColumnHeaderRenderer l = (ColumnHeaderRenderer) getTableHeader().getDefaultRenderer(); l.setHorizontalAlignment(SwingConstants.CENTER); } /** Creates a new instance. */ public OMETreeTable() { super(); initialize(); } /** * Create an instance of the treetable. * * @param model The tree model. */ public OMETreeTable(TreeTableModel model) { super(model); setTableModel(model); initialize(); } /** * Sets the tree model. * * @param model The value to set. */ public void setTableModel(TreeTableModel model) { setTreeTableModel(model); } /** Sets the default high lighter for this table. */ protected void setDefaultHighLighter() { Highlighter h = HighlighterFactory.createAlternateStriping( UIUtilities.BACKGROUND_COLOUR_EVEN, UIUtilities.BACKGROUND_COLOUR_ODD); addHighlighter(h); addHighlighter(new SelectionHighLighter(this)); } /** * Return <code>true</code> if the left button was clicked, * <code>false</code> otherwise. * * @param e The mouse event to handle. * @return See above. */ protected boolean leftClick(MouseEvent e) { return (e.getButton() == MouseEvent.BUTTON1); } /** * Sets the mouse listener for mouse events and attach it to the methods * onLeftMouseDown(), onRightMouseDown() */ protected void setListeners() { MouseListener mouseListener = new MouseListener() { public void mouseClicked(MouseEvent e) { onMouseClicked(e); } public void mouseEntered(MouseEvent e) { onMouseEnter(e); } public void mouseExited(MouseEvent e) { onMouseExit(e); } public void mousePressed(MouseEvent e) { onMousePressed(e); } public void mouseReleased(MouseEvent e) { onMouseReleased(e); } }; addMouseListener(mouseListener); } /** * MouseEvent called from mouseListener. * This Event responds to mouseClicked events. * * @param e The mouse event to handle. */ protected void onMouseClicked(MouseEvent e) {} /** * MouseEvent called from mouseListener. * This Event responds to mouse released events. * * @param e The mouse event to handle. */ protected void onMouseReleased(MouseEvent e) {} /** * MouseEvent called from mouseListener. * This Event responds to mouse pressed events. * * @param e The mouse event to handle. */ protected void onMousePressed(MouseEvent e) {} /** * MouseEvent called from mouseListener. * This Event responds to mouse enter events. * * @param e The mouse event to handle. */ protected void onMouseEnter(MouseEvent e) {} /** * MouseEvent called from mouseListener. * This Event responds to mouseExit events. * * @param e The mouse event to handle. */ protected void onMouseExit(MouseEvent e) {} /** * Sets the tree expansion listener for the tree. * Attach the collapse and expand events to the onNodeNavigation * method. */ protected void setTreeExpansionListener() { treeExpansionListener = new TreeExpansionListener() { public void treeCollapsed(TreeExpansionEvent e) { onNodeNavigation(e, false); } public void treeExpanded(TreeExpansionEvent e) { onNodeNavigation(e, true); } }; addTreeExpansionListener(treeExpansionListener); } /** * This method is called when a node in the tree is expanded or * collapsed. * * @param e The tree event. * @param expanded Pass <code>true</code> if the node was expanded, * <code>false</code> otherwise. */ protected void onNodeNavigation(TreeExpansionEvent e, boolean expanded) { OMETreeNode node = (OMETreeNode) e.getPath().getLastPathComponent(); node.setExpanded(expanded); } /** * Sets the default editors for the cells in the table. This includes * editors for cells containing: int, long, string, booleans, * floats, longs, doubles. */ protected void setDefaultEditors() { Iterator<Class<?>> classIterator = DEFAULT_EDITORS.keySet().iterator(); Class<?> classType; DefaultCellEditor editorType; while(classIterator.hasNext()) { classType = classIterator.next(); editorType = DEFAULT_EDITORS.get(classType); this.setDefaultEditor(classType, editorType); } } /** * Sets the default renderers for the cells in the table. This includes * renderers for cells containing: dates, int, long, string, booleans, * floats, longs, doubles, colour. */ protected void setDefaultRenderers() { Iterator<Class<?>> classIterator = DEFAULT_RENDERERS.keySet().iterator(); Class<?> classType; TableCellRenderer rendererType; while (classIterator.hasNext()) { classType = classIterator.next(); rendererType = DEFAULT_RENDERERS.get(classType); setDefaultRenderer(classType, rendererType); } } /** * Expands the row with the node in it. * * @param node The node to handle. */ public void expandNode(OMETreeNode node) { if (node != null) expandPath(node.getPath()); } /** * Collapses the row with the node in it. * * @param node The node to handle. */ public void collapseNode(OMETreeNode node) { if (node != null) collapsePath(node.getPath()); } /** * Overrides the {@link JXTreeTable#expandPath(TreePath)} * Adds extra control to set the expanded flag in the OMETreeNode. * @see JXTreeTable#expandPath(TreePath) */ public void expandPath(TreePath path) { super.expandPath(path); if (path == null) return; OMETreeNode node = (OMETreeNode) path.getLastPathComponent(); if (node != null) node.setExpanded(true); } /** * Overrides the {@link JXTreeTable#expandRow(int)} * Adds extra control to set the expanded flag in the OMETreeNode. * @see JXTreeTable#expandRow(int) */ public void expandRow(int row) { super.expandRow(row); OMETreeNode node = getNodeAtRow(row); if (node != null) node.setExpanded(true); } /** * Overrides the {@link JXTreeTable#expandAll()} * Adds extra control to set the expanded flag in the OMETreeNode. * @see JXTreeTable#expandAll() */ public void expandAll() { super.expandAll(); MutableTreeTableNode root = (MutableTreeTableNode) getTreeTableModel().getRoot(); if (root == null) return; for (MutableTreeTableNode node : ((OMETreeNode) root).getChildList()) ((OMETreeNode) node).setExpanded(true); } /** * Helper method to get the node at row. * * @param row The selected row. * @return See above. */ public OMETreeNode getNodeAtRow(int row) { TreePath path = getPathForRow(row); if (path == null) return null; return (OMETreeNode) path.getLastPathComponent(); } /** * Gets the row a node is at. * * @param node The node. * @return See above. */ public int getRow(OMETreeNode node) { if (node == null) return -1; return getRowForPath(node.getPath()); } /** * Returns <code>true</code> if the cell editable for this node and column, * <code>false</code> otherwise. * * @param node The node of the tree. * @param column The field to edit. * @return See above. */ public boolean isCellEditable(Object node, int column) { return getTreeTableModel().isCellEditable(node, column); } /** * Selects a node. * * @param node The node to select. */ public void selectNode(OMETreeNode node) { int row = getRow(node); selectionModel.addSelectionInterval(row, row); } /** * Overrides the {@link JXTreeTable#collapsePath(TreePath)} * Adds extra control to set the expanded flag in the OMETreeNode. * @see JXTreeTable#collapsePath(TreePath) */ public void collapsePath(TreePath path) { super.collapsePath(path); if (path == null) return; OMETreeNode node = (OMETreeNode) path.getLastPathComponent(); if (node != null) node.setExpanded(false); } /** * Overrides the {@link JXTreeTable#collapseRow(int)} * Adds extra control to set the expanded flag in the OMETreeNode. * @see JXTreeTable#collapseRow(int) */ public void collapseRow(int row) { super.collapseRow(row); OMETreeNode node = getNodeAtRow(row); if (node != null) node.setExpanded(false); } /** * Overrides the {@link JXTreeTable#collapseAll()} * Adds extra control to set the expanded flag in the OMETreeNode. * @see JXTreeTable#collapseAll() */ public void collapseAll() { super.collapseAll(); MutableTreeTableNode root = (MutableTreeTableNode) getTreeTableModel().getRoot(); if (root == null) return; for (MutableTreeTableNode node : ((OMETreeNode) root).getChildList()) ((OMETreeNode) node).setExpanded(true); } /** * Overridden to set the various renderer. * @see JXTreeTable#setTreeTableModel(TreeTableModel) */ public void setTreeTableModel(TreeTableModel model) { super.setTreeTableModel(model); setColumnSelectionAllowed(false); setRowSelectionAllowed(true); setCellSelectionEnabled(false); setTreeExpansionListener(); setListeners(); setDefaultRenderers(); setDefaultEditors(); setDefaultHighLighter(); } }